package patient

import (
	"api-gateway/basic/config"
	proto "api-gateway/basic/proto"
	"api-gateway/handler/request"
	"context"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"time"
)

// ==================== 预约挂号流程 ====================

// GetDepartmentDoctors 按科室获取医师列表
// GET /patient/doctors/by-department?department_id=123
func GetDepartmentDoctors(c *gin.Context) {
	deptIDStr := c.Query("department_id")
	deptID, err := strconv.ParseUint(deptIDStr, 10, 64)
	if err != nil || deptID == 0 {
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少或无效的 department_id"})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// RPC调用
	resp, err := config.PatientClient.GetDoctorsByDepartment(ctx, &proto.GetDoctorsByDepartmentRequest{
		Department: "",
		Page:       0,
		PageSize:   0,
	})
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "获取医师列表失败"})
		return
	}

	// 转换响应数据
	var doctors []gin.H
	for _, doctor := range resp.Doctors {
		doctors = append(doctors, gin.H{
			"name":  doctor.Name,
			"title": doctor.Title,
		})
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  resp.Message,
		"data": doctors,
	})
}

//// GetDiseaseDepartments 按疾病获取科室列表
//// GET /patient/departments/by-disease?disease=感冒
//func GetDiseaseDepartments(c *gin.Context) {
//	disease := c.Query("disease")
//	if disease == "" {
//		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少 disease 参数"})
//		return
//	}
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用
//	resp, err := config.PatientClient.SearchDepartmentsByDisease(ctx, &proto.SearchDepartmentsByDiseaseRequest{
//		Disease: disease,
//	})
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "获取科室列表失败"})
//		return
//	}
//
//	// 转换响应数据
//	var departments []gin.H
//	for _, dept := range resp.Departments {
//		departments = append(departments, gin.H{
//			"id":   dept.Id,
//			"name": dept.Name,
//		})
//	}
//
//	c.JSON(http.StatusOK, gin.H{
//		"code": 200,
//		"msg":  resp.Message,
//		"data": departments,
//	})
//}

// GetDiseaseDoctors 疾病对应的医师列表
// GET /patient/doctors/by-disease?disease=高血压
//func GetDiseaseDoctors(c *gin.Context) {
//	disease := c.Query("disease")
//	if disease == "" {
//		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少 disease 参数"})
//		return
//	}
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用
//	resp, err := config.PatientClient.SearchDoctorsByDisease(ctx, &proto.SearchDoctorsByDiseaseRequest{
//		Disease: disease,
//	})
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "获取医师列表失败"})
//		return
//	}
//
//	// 转换响应数据
//	var doctors []gin.H
//	for _, doctor := range resp.Doctors {
//		doctors = append(doctors, gin.H{
//			"id":   doctor.Id,
//			"name": doctor.Name,
//			"dept": doctor.DepartmentName,
//		})
//	}
//
//	c.JSON(http.StatusOK, gin.H{
//		"code": 200,
//		"msg":  resp.Message,
//		"data": doctors,
//	})
//}

// GetDoctorSchedule 医师排班时间表
// GET /patient/schedule?doctor_id=5&date=2025-11-07
func GetDoctorSchedule(c *gin.Context) {
	doctorIDStr := c.Query("doctor_id")
	date := c.Query("date")

	doctorID, err := strconv.ParseUint(doctorIDStr, 10, 64)
	if err != nil || doctorID == 0 {
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "无效的 doctor_id"})
		return
	}
	if date == "" {
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少 date 参数 (格式: YYYY-MM-DD)"})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// RPC调用
	resp, err := config.PatientClient.GetDoctorSchedule(ctx, &proto.GetDoctorScheduleRequest{
		DoctorId: int64(doctorID),
		Date:     date,
	})
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "获取排班信息失败"})
		return
	}

	// 转换响应数据
	var schedules []gin.H
	for _, schedule := range resp.Schedules {
		schedules = append(schedules, gin.H{
			"schedule_id": schedule.Id,
			"time_slot":   schedule.EndTime,
		})
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  resp.Message,
		"data": schedules,
	})
}

// GetDoctorClinicInfo 医师门诊信息
// GET /patient/clinic/5
//func GetDoctorClinicInfo(c *gin.Context) {
//	doctorID := c.Param("doctor_id")
//	id, err := strconv.ParseUint(doctorID, 10, 64)
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "无效的医生ID"})
//		return
//	}
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用
//	resp, err := config.PatientClient.GetDoctorClinicInfo(ctx, &proto.GetDoctorClinicInfoRequest{
//		DoctorId: int64(id),
//	})
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "获取门诊信息失败"})
//		return
//	}
//
//	c.JSON(http.StatusOK, gin.H{
//		"code": 200,
//		"msg":  resp.Message,
//		"data": gin.H{
//			"doctor_id":   id,
//			"clinic_name": resp.ClinicName,
//			"room":        resp.Room,
//			"hospital":    resp.Hospital,
//		},
//	})
//}

// CreateAppointment 创建预约订单
// POST /patient/appointment
func CreateAppointment(c *gin.Context) {
	var req request.CreatePrescriptionReq
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "参数错误"})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// RPC调用
	resp, err := config.PatientClient.CreateAppointment(ctx, &proto.CreateAppointmentRequest{
		PatientId:  int64(req.PatientID),
		DoctorId:   int64(req.DoctorID),
		ScheduleId: int64(req.ScheduleID),
		VisitType:  int32(req.VisitType),
	})
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "创建预约失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  resp.Message,
		"data": gin.H{
			"order_id": resp.OrderId,
			"status":   "待支付",
		},
	})
}

// GetAppointmentDetail 预约详情
// GET /patient/appointment/ORD20251106123456
func GetAppointmentDetail(c *gin.Context) {
	orderID := c.Param("order_id")
	if orderID == "" {
		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少订单号"})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// RPC调用
	resp, err := config.PatientClient.GetAppointmentDetail(ctx, &proto.GetAppointmentDetailRequest{
		AppointmentId: 0,
		UserId:        0,
	})
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "获取预约详情失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  resp.Message,
		"data": gin.H{
			"order_id": orderID,
		},
	})
}

// SelectPatient 选择就诊人
// POST /patient/select-patient
//func SelectPatient(c *gin.Context) {
//	type Request struct {
//		PatientID uint `json:"patient_id" binding:"required"`
//	}
//	var req Request
//	if err := c.ShouldBindJSON(&req); err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "参数错误"})
//		return
//	}
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用 - 验证患者是否属于当前用户
//	resp, err := config.PatientClient.ValidatePatientOwnership(ctx, &proto.ValidatePatientOwnershipRequest{
//		PatientId: int64(req.PatientID),
//	})
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "验证就诊人失败"})
//		return
//	}
//
//	if !resp.IsValid {
//		c.JSON(http.StatusOK, gin.H{"code": 403, "msg": "无权选择该就诊人"})
//		return
//	}
//
//	c.JSON(http.StatusOK, gin.H{
//		"code": 200,
//		"msg":  "就诊人已选择",
//		"data": gin.H{"patient_id": req.PatientID},
//	})
//}

//// PayWithAlipay 支付宝支付
//func PayWithAlipay(c *gin.Context) {
//	type Request struct {
//		OrderID string `json:"order_id" binding:"required"`
//	}
//	var req Request
//	if err := c.ShouldBindJSON(&req); err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少订单号"})
//		return
//	}
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用 - 生成支付宝支付链接
//	resp, err := config.PatientClient.GeneratePaymentLink(ctx, &proto.GeneratePaymentLinkRequest{
//		OrderId:     req.OrderID,
//		PaymentType: "alipay",
//	})
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "生成支付链接失败"})
//		return
//	}
//
//	c.JSON(http.StatusOK, gin.H{
//		"code": 200,
//		"msg":  resp.Message,
//		"data": gin.H{"pay_url": resp.PayUrl},
//	})
//}
//
//// PayWithWechat 微信支付
//func PayWithWechat(c *gin.Context) {
//	type Request struct {
//		OrderID string `json:"order_id" binding:"required"`
//	}
//	var req Request
//	if err := c.ShouldBindJSON(&req); err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少订单号"})
//		return
//	}
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用 - 生成微信支付参数
//	resp, err := config.PatientClient.GenerateWechatPayParams(ctx, &proto.GenerateWechatPayParamsRequest{
//		OrderId: req.OrderID,
//	})
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "生成支付参数失败"})
//		return
//	}
//
//	c.JSON(http.StatusOK, gin.H{
//		"code": 200,
//		"msg":  resp.Message,
//		"data": gin.H{
//			"appid":     resp.AppId,
//			"prepay_id": resp.PrepayId,
//			"code_url":  resp.CodeUrl,
//		},
//	})
//}
//
//// PayOffline 到院支付
//func PayOffline(c *gin.Context) {
//	type Request struct {
//		OrderID string `json:"order_id" binding:"required"`
//	}
//	var req Request
//	if err := c.ShouldBindJSON(&req); err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 400, "msg": "缺少订单号"})
//		return
//	}
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用 - 更新订单状态为到院支付
//	resp, err := config.PatientClient.SetOfflinePayment(ctx, &proto.SetOfflinePaymentRequest{
//		OrderId: req.OrderID,
//	})
//	if err != nil {
//		c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "设置到院支付失败"})
//		return
//	}
//
//	c.JSON(http.StatusOK, gin.H{
//		"code": 200,
//		"msg":  resp.Message,
//		"data": gin.H{"order_id": req.OrderID, "pay_method": "offline"},
//	})
//}
//
//// AlipayCallback 支付宝回调
//func AlipayCallback(c *gin.Context) {
//	// 获取表单参数
//	tradeNo := c.PostForm("trade_no")
//	outTradeNo := c.PostForm("out_trade_no")
//	tradeStatus := c.PostForm("trade_status")
//
//	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//	defer cancel()
//
//	// RPC调用 - 处理支付宝回调
//	_, _ = config.PatientClient.ProcessPaymentCallback(ctx, &proto.PaymentCallbackRequest{
//		TradeNo:     tradeNo,
//		OutTradeNo:  outTradeNo,
//		TradeStatus: tradeStatus,
//		PaymentType: "alipay",
//	})
//
//	// 返回success告知支付宝不要重试
//	c.String(http.StatusOK, "success")
//}
//
//// WechatCallback 微信回调
//func WechatCallback(c *gin.Context) {
//	// 读取XML数据
//	var xmlData struct {
//		ReturnCode    string `xml:"return_code"`
//		OutTradeNo    string `xml:"out_trade_no"`
//		TransactionId string `xml:"transaction_id"`
//		ResultCode    string `xml:"result_code"`
//	}
//
//	if err := c.ShouldBindXML(&xmlData); err == nil && xmlData.ReturnCode == "SUCCESS" && xmlData.ResultCode == "SUCCESS" {
//		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
//		defer cancel()
//
//		// RPC调用 - 处理微信回调
//		_, _ = config.PatientClient.ProcessPaymentCallback(ctx, &proto.PaymentCallbackRequest{
//			TradeNo:     xmlData.TransactionId,
//			OutTradeNo:  xmlData.OutTradeNo,
//			TradeStatus: xmlData.ResultCode,
//			PaymentType: "wechat",
//		})
//	}
//
//	// 返回成功响应给微信服务器
//	c.Header("Content-Type", "application/xml")
//	c.String(http.StatusOK, `<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>`)
//}
